<?php
/**
 * Created by PhpStorm.
 * User: fengdh
 * Date: 2019/8/8
 * Time: 14:49
 */

namespace console\controllers;

use business\base\models\CronTaskModel;
use business\search\models\UnindexSearchDataModel;
use common\storage\JobStorage;
use common\utils\DateTimeUtils;
use yii\console\Controller;

class BaseIndexController extends Controller
{
    protected $_every_time_number = 100;    //每次最大更新次数

    //增量方式更新时: 通过last_modified_time查找时，默认查找离当前时间多少分钟内的变更项
    const DEFAULT_INCREMENT_TIME = '3';

    //增量方式更新时: 记录最近一次供应商索引查询的时间的key
    const LATEST_PLATFORM_SUPPLIER_QUERY_TIME_KEY = "elasticsearchLastPlatformSupplierQueryTime";

    //增量方式更新时: 记录最近一次开发商索引查询的时间的key
    const LATEST_PLATFORM_DEVELOPER_QUERY_TIME_KEY = "elasticsearchLastPlatformDeveloperQueryTime";

    //增量方式更新时: 记录最近一次商机索引查询的时间的key
    const LATEST_PLATFORM_PROCUREMENT_QUERY_TIME_KEY = "elasticsearchLastPlatformProcurementQueryTime";

    /**
     * 消费场景:
     * scenario_storage: 从存储器(Set,Queue)中读取任务(scenario_storage)
     * scenario_directly: 直接一步执行定时任务，不通过存储器直接消费
     */
    const CONS_SCENARIO_DIRECTLY = 'directly';
    const CONS_SCENARIO_STORAGE = 'storage';

    /**
     * 存储类型: 集合，队列等
     */
    const STORAGE_SET = 'set';
    const STORAGE_QUEUE = 'queue';

    /**
     * @var null 任务名称(子类Controller的特定格式名称 xx/CronDemoController ==> cron-demo)
     */
    public $taskName = null;

    /**
     * @var StorageInterface 存储驱动(set|queue => redis)
     */
    public $storage = null;

    /**
     * @var string  存储数据结构:set|queue
     */
    public $storageStructure = null;

    /**
     * @var string 存储数据结构的key值
     */
    public $storageKey = '';

    /**
     * @var mixed 业务中产生的上次查询时间
     */
    public $lastQueryTime = null;

    /**
     * @var mixed 具体推入到存储中的单个任务(元素)
     */
    public $job = null;

    /**
     * @var mixed 任务启动时间
     */
    public $taskStartTime = null;

    /**
     * 消费任务最长执行时间
     * @var int
     */
    public $maxExecuteSeconds = 600;
    /**
     * 任务描述
     * @var
     */
    public $description;

    /**
     * 保存非合规索引数据
     * @param $type
     * @param $title
     * @param $key
     * @param $reason
     */
    protected function saveUnIndexData($type, $title, $key, $reason)
    {
        $model = new UnindexSearchDataModel();
        $model->type = $type;
        $model->title = $title;
        $model->key = $key;
        $model->reason = $reason;
        $model->created_time = DateTimeUtils::now();
        $model->save();
    }

    /**
     * 获取任务名称taskName(约定:定时任务的最后请求路径即taskName: xxx/CronDemoController ==> cron-demo)
     *
     * @return string 任务名称
     */
    private function getTaskName()
    {
        if (empty($this->taskName)) {
            $fullNameArray = explode('\\', preg_replace('/Controller/', '', get_class($this)));
            $this->taskName = strtolower(preg_replace('/((?<=[a-z])(?=[A-Z]))/', '-', array_pop($fullNameArray)));
        }
        return $this->taskName;
    }

    /**
     * 初始化任务
     *
     * @param string $taskName
     * @throws Exception
     */
    protected function initTask($taskName = '')
    {
        if (empty($taskName)) {
            $taskName = $this->getTaskName();
        }
        /** @var CronTaskModel $task */
        $task = CronTaskModel::find()->where(['task_name' => $taskName, 'is_valid' => 1])->one();
        if (!empty($task)) {
            $this->storage = new JobStorage();
            $this->storage->setStructure($task->storage_structure);
            $this->storageStructure = $task->storage_structure;
            if ($task->max_execute_time > 0) {
                $this->maxExecuteSeconds = $task->max_execute_time;
            }
            $this->storageKey = $task->storage_key;
            $this->lastQueryTime = $task->last_query_time;
            $this->description = $task->remark;
        } else {
            throw new Exception('The cron task name dose not exist or invalid! ==> ' . $taskName);
        }
        $this->taskStartTime = time();
    }
}